//Clases base (implementacion de patrones)

//--------------- Gestion de objetos de uso comun en la aplicacion ---------------

var EBRegistry = Class.create( );
EBRegistry.prototype = {
    
    initialize: function( ) {
        this.cache = new Array( );
    },
    
    setEntry: function ( key, item ) {
        this.cache[ key ] = item;
    },
    
    getEntry: function ( key ) {
        return this.cache[ key ];
    },
    
    isEntry: function ( key ) {
    	if( this.getEntry( key ) ) {
    		return( true );
    	}
    	else {
    		return( false );
    	}
    }
    
}


//---------------- Clase base para objetos observables (caso simple, solo un observador)

var EBObservable = Class.create( );
EBObservable.prototype = {

	initialize: function( ) {
		this.observer = null;
		this.state = null;
	},
	
	notifyObserver: function( ) {
		this.observer.update( this );
	},
	
	addObserver: function( observer ) {
		this.observer = observer;
	},
	
	removeObserver: function( ) {
		this.observer = null;
	},
	
	getState: function( ) {
		return( this.state );
	},
	
	changeState: function( state ) {
		this.state = state;
		if( this.observer ) {
			this.notifyObserver( );
		}
	},
    
    isReady: function( ) {
    	return( this.state == 'ready' );
    },	
	
    isPreparing: function( ) {
    	return( this.state == 'preparing' );
    },    
    
    isParsing: function( ) {
    	return( this.state == 'parsing' );
    },
    
    isInTransition: function( ) {
    	return( this.state == 'inTransition' );
    },    
    
    isUnloaded: function( ) {
    	return( this.state == 'unloaded' );
    },    
    
    isLoaded: function( ) {
    	return( this.state == 'loaded' );
    },
	    
    isLoading: function( ) {
    	return( this.state == 'loading' );
    },
        
    isError: function( ) {
    	return( this.state == 'error' );
    },
    
    isWarning: function( ) {
    	return( this.state == 'warning' );
    }

}


//--------------- Proveedor de datos AJAX  ---------------

var EBDataProvider = Class.create( );

EBDataProvider.prototype = Object.extend( new EBObservable( ), {
	initialize: function( id, url ) {
		this.state = 'unloaded'; //{unloaded, loaded, parsing, loading, error}
		this.id = id;
		this.url = url;
		this.params = null;
		this.xml = null;
		this.data = new Array( );
		this.updateTime = null;
		this.timer = null;
	},
	
	stopTimer: function( ) {
		this.timer.stop();
	},
	
	startTimer: function( ) {
		//Redefinir en clases derivadas
	},	
	
	setParams: function( params ) {
		this.params = params;
	},
	
	setXml: function( xml ) {
		this.changeState( 'parsing' );
		this.xml = xml;
		if( this.parseXml( ) ) {
			this.changeState( 'loaded' );
		}
		else {
			this.changeState( 'warning' );
		}
	},
	
	parseXml: function( ) {
		//Implementar en las clases derivadas
	},
	
	getData: function( ) {
		return( this.data );
	},
	
	getDataItem: function( index ) {
		return( this.data[ index ] );
	},
	
	manageLoadError: function( ) {
		this.changeState( 'error' );
	},
	
	reset: function( ) {
		this.data.clear( );
		this.changeState( 'unloaded' );
	},
	
	load: function( force ) {
		if( this.isLoaded( ) && !force ) {
			if( this.observer ) {
				this.notifyObserver( );
			}
			return;
		}
		
		this.changeState( 'loading' );
    	var AjaxCall = new Ajax.Request( this.url,
    	{
    		method: 'get',
    		parameters: this.params + "&ms=" + new Date().getTime(),
    		options: { asynchronous: true },
    		
    		onComplete: function( response ) {
    			this.setXml( response.responseXML );
    		}.bind( this ),
    		
    		onFailure: function( r, o ) {
    			this.manageLoadError( );
    		}.bind( this ),
    		
    		onException: function( r, e ) {
    			this.manageLoadError( );
    		}.bind( this )
    		
    	}
    	);
	}
	
}
);

var EBDateTool = Class.create( );
EBDateTool.prototype = {

	initialize: function(date) {
		this.date = date;
	},
	
	normalize: function(value) {
		value = value.toString();
		if(value.length == 1 ) return "0" + value;
		else return value;
	},
	
	getEventString: function( ) {
		return this.normalize(this.date.getDate()) + '-' + this.normalize(this.date.getMonth()+1) + '-' + this.date.getFullYear() + ' a las ' + this.normalize(this.date.getHours()) + ":" + this.normalize(this.date.getMinutes());
	},
	
	getLabelString: function() {
		var currentTime = $RGE('zoom').currentTime;
		var output = '';
		if(currentTime == 'days') {
			output = this.normalize(this.date.getDate()) + '-' + this.normalize(this.date.getMonth()+1) + '-' + this.date.getFullYear();
		}
		else if(currentTime == 'months') {
			output = this.normalize(this.date.getMonth()+1) + '-' + this.date.getFullYear();
		}
		else if(currentTime == 'years') {
			output = this.normalize(this.date.getFullYear());
		}
		else {
			output = this.normalize(this.date.getDate()) + '-' + this.normalize(this.date.getMonth()+1) + '-' + this.date.getFullYear() + ' ' + this.normalize(this.date.getHours()) + ":" + this.normalize(this.date.getMinutes());
		}
		return output;
	},
	
	getString: function() {
		var output =  this.date.getFullYear() + this.normalize(this.date.getMonth()+1) + this.normalize(this.date.getDate()) + this.normalize(this.date.getHours()) + this.normalize(this.date.getMinutes()) + this.normalize(this.date.getSeconds());
		return output;
	}
	
}


var $RGC = function( ) {
	return( registry.getEntry( 'config' ) );
}

var $RGE = function( key ) {
	return( registry.getEntry( key ) );
}
